'use strict';

const Controller = require('./base');
const fs = require('fs');
const path = require('path');
const childProcess = require('child_process');
const { v4: v4uuid } = require('uuid');
const { notePath, ignoreDirs } = require('../utils/getPath');

class CreateController extends Controller {
  async run() {
    const { ctx } = this;
    const ws = ctx.websocket;

    ws.on('message', async msg => {
      const data = JSON.parse(msg.toString());
      if (data.type === '__CREATE__ARTICLE__') {
        const categoryMap = await ctx.service.category.getCategoryMap();
        await this.writeFile(data.data, categoryMap);
        await this.createArticle(data.data);
        await this.git(data.data, categoryMap);
      }
    });
  }

  // 向 md-note 文件夹中创建新的文章
  async writeFile(data, categoryMap) {
    const { ctx } = this;
    const ws = ctx.websocket;

    ws.send('writeFile start');

    const firstCategoryText = categoryMap[data.firstCategory];
    const secondCategoryText = categoryMap[data.secondCategory];

    let dirPath = notePath;
    const firstDir = fs.readdirSync(dirPath);
    for (const firstDirName of firstDir) {
      if (ignoreDirs.includes(firstDirName)) continue;

      if (firstDirName.includes(firstCategoryText)) {
        dirPath = path.join(dirPath, firstDirName);
        ws.send('get firstDir：' + dirPath);
        break;
      }
    }

    const secondDir = fs.readdirSync(dirPath);
    for (const secondDirName of secondDir) {
      if (ignoreDirs.includes(secondDirName)) continue;

      if (secondDirName.includes(secondCategoryText)) {
        dirPath = path.join(dirPath, secondDirName);
        ws.send('get secondDir：' + dirPath);
        break;
      }
    }

    fs.writeFileSync(path.join(dirPath, `${data.title}.md`), data.content);
    ws.send(`writeFile success, add article ${data.title}.md to ${dirPath}`);
  }

  // 向数据库中插入新的文章
  async createArticle(data) {
    const { ctx } = this;
    const ws = ctx.websocket;

    ws.send('create article start');

    const list = await ctx.service.article.selectByCategory(data.firstCategory, data.secondCategory);
    const maxSort = list[0]._source.sort + 1;
    ws.send('create max sort success, the sort is ' + maxSort);

    const article = {
      id: v4uuid(),
      title: data.title,
      content: data.content,
      sort: maxSort,
      first_category: data.firstCategory,
      second_category: data.secondCategory,
      time: new Date().getTime(),
    };
    const result = await ctx.service.article.insert(article);

    ws.send(`insert article ${result ? 'success' : 'error'}`);
  }

  // 更新 md-note git 仓库
  async git(data, categoryMap) {
    const { ctx } = this;
    const ws = ctx.websocket;

    ws.send('git start');

    ws.send('exec: "git add ."');
    const gitAdd = childProcess.execSync('git add .', {
      cwd: notePath,
    });
    ws.send('exec "git add ." end，the result is ' + gitAdd.toString());

    const exec = `git commit -m "feat: add article ${categoryMap[data.firstCategory]}/${categoryMap[data.secondCategory]}/${data.title}.md"`;
    ws.send(`exec: ${exec}`);
    const gitCommit = childProcess.execSync(exec, { cwd: notePath });
    ws.send('git commit end，the result is ' + gitCommit.toString());

    ws.send('exec: "git push"');
    const gitPush = childProcess.execSync('git push', { cwd: notePath });
    ws.send('git push end，the result is ' + gitPush.toString());
  }
}

module.exports = CreateController;
